﻿using OvenParameterForm.Device;
using OvenParameterForm.Model;
using OvenParameterForm.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace OvenParameterForm.Technics
{
    /// <summary>
    /// 工艺类基类，
    /// </summary>
    public abstract class TechnicsBaseClass : IDisposable
    {
        private bool disposedValue;
        /// <summary>
        /// 工艺子流程集合，保温工艺下含有子流程
        /// </summary>
        public List<TechnicsBaseClass> 子流程 = new List<TechnicsBaseClass>();
        /// <summary>
        /// 发送状态委托，用以向外界发送工艺状态
        /// </summary>
        public Func<string,string> sendStatus;
        /// <summary>
        /// 停止工艺信号,默认flase
        /// </summary>
        public bool flagStopTechnics=false;
        public string ovenName;
        private string path = Application.StartupPath + "\\系统配置\\";
        internal ovenPLCAddress ovenPLCaddress=new ovenPLCAddress();
        /// <summary>
        /// 根据烘箱名称查找该烘箱的PLC地址集，并加载到地址类中
        /// </summary>
        /// <param name="name"></param>
       public TechnicsBaseClass(string name)
        {
            ovenName = name;
            XDocument xdo=XDocument.Load(path+name+".xml");
            ovenPLCaddress = PublicFunc.XMLToClass<ovenPLCAddress>(xdo.Root.Element(ovenPLCaddress.GetType().Name), ovenPLCaddress);
        }
        public TechnicsBaseClass(string[] strings)
        {
            
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: 释放托管状态(托管对象)
                    runTimer?.Change(-1, 1000);
                    runTimer?.Dispose();
                }
                // TODO: 释放未托管的资源(未托管的对象)并重写终结器
                // TODO: 将大型字段设置为 null
                disposedValue = true;
            }
        }
        // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
        // ~TechnicsBaseClass()
        // {
        //     // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
        //     Dispose(disposing: false);
        // }

        public void Dispose()
        {
            // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
        /// <summary>
        /// 工艺运行，内部起一个线程计时器并启动，困在一个while循环等待条件满足
        /// </summary>
        public virtual void Run()
        {
            runTimer = new System.Threading.Timer(updatetime, null, Timeout.Infinite, 1000);
            runTimer.Change(0, 1000);
            while (!Complete()&&!flagStopTechnics)
            {

              
             
            }
            if (flagStopTechnics)
            {
                ClearVariable();
                sendStatus("流程已停止");
            }
            runTimer.Change(-1, 1000);
        }
        /// <summary>
        /// 线程计时器的回调方法
        /// </summary>
        /// <param name="state"></param>
        protected abstract void updatetime(object state);
        /// <summary>
        /// 更新线程计时器，用以计时或更新参数状态
        /// </summary>
        protected System.Threading.Timer runTimer ;
        /// <summary>
        /// 工艺完成的判断函数
        /// </summary>
        /// <returns></returns>
        protected abstract bool Complete();
        /// <summary>
        /// 清空变量函数
        /// </summary>
        protected abstract void ClearVariable();
    }
}
